/*
 * Copyright (c) 2022 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef SPAPTIAL_ALGORITHM_HANDLE_H
#define SPAPTIAL_ALGORITHM_HANDLE_H

#include <mutex>
#include <string>
#include <regex>
#include <unordered_map>
#include "msdp_algorithm_interface.h"

namespace OHOS {
namespace Msdp {
class MsdpAlgorithmHandle {
public:
    MsdpAlgorithmHandle() = default;
    virtual ~MsdpAlgorithmHandle() = default;
    virtual void Clear() = 0;
};

class CommonAlgorithmHandle : public MsdpAlgorithmHandle {
public:
    CommonAlgorithmHandle()
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
    virtual ~CommonAlgorithmHandle() {}
    void Clear() override
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
public:
    void *handle;
    MsdpAlgorithmInterface *(*create)();
    void *(*destroy)(MsdpAlgorithmInterface *);
    MsdpAlgorithmInterface *pAlgorithm;
};

class DirectionAlgorithmHandle : public MsdpAlgorithmHandle {
public:
    DirectionAlgorithmHandle()
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
    virtual ~DirectionAlgorithmHandle() {}
    void Clear() override
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
public:
    void *handle;
    MsdpAlgorithmInterface *(*create)();
    void *(*destroy)(MsdpAlgorithmInterface *);
    MsdpAlgorithmInterface *pAlgorithm;
};

class DistanceAlgorithmHandle : public MsdpAlgorithmHandle {
public:
    DistanceAlgorithmHandle()
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
    virtual ~DistanceAlgorithmHandle() {}
    void Clear() override
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
public:
    void *handle;
    MsdpAlgorithmInterface *(*create)();
    void *(*destroy)(MsdpAlgorithmInterface *);
    MsdpAlgorithmInterface *pAlgorithm;
};

class AngleAlgorithmHandle : public MsdpAlgorithmHandle {
public:
    AngleAlgorithmHandle()
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
    virtual ~AngleAlgorithmHandle() {}
    void Clear() override
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
public:
    void *handle;
    MsdpAlgorithmInterface *(*create)();
    void *(*destroy)(MsdpAlgorithmInterface *);
    MsdpAlgorithmInterface *pAlgorithm;
};

class InnerOuterAlgorithmHandle : public MsdpAlgorithmHandle {
public:
    InnerOuterAlgorithmHandle()
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
    virtual ~InnerOuterAlgorithmHandle() {}
    void Clear() override
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
public:
    void *handle;
    MsdpAlgorithmInterface *(*create)();
    void *(*destroy)(MsdpAlgorithmInterface *);
    MsdpAlgorithmInterface *pAlgorithm;
};

class ExistAlgorithmHandle : public MsdpAlgorithmHandle {
public:
    ExistAlgorithmHandle()
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
    virtual ~ExistAlgorithmHandle() {}
    void Clear() override
    {
        handle = nullptr;
        create = nullptr;
        destroy = nullptr;
        pAlgorithm = nullptr;
    }
public:
    void *handle;
    MsdpAlgorithmInterface *(*create)();
    void *(*destroy)(MsdpAlgorithmInterface *);
    MsdpAlgorithmInterface *pAlgorithm;
};

class SpatialAlgorithmHandle {
public:
    SpatialAlgorithmHandle() {}
    ~SpatialAlgorithmHandle() {}
    bool Init();
    int32_t CheckPreLoadService(void);
    int32_t CheckAndEnforceService(const AlgorithmType &type, bool bCreate = false);
    int32_t InstallAlllib(bool bCreate = false);
    int32_t LoadAllLib(bool bCreate = true);
    MsdpAlgorithmInterface *GetAlgoInstance(const AlgorithmType &type);
    void UninstallAllLib();
private:
    int32_t GetServiceDll(const AlgorithmType &type, std::string &dlname);
    int32_t LoadDirectionLib(const std::string &dlname, bool bCreate);
    int32_t UnloadDirectionLib(bool bPreLoad);
    int32_t LoadDistanceLib(const std::string &dlname, bool bCreate);
    int32_t UnloadDistanceLib(bool bPreLoad);
    int32_t LoadAngleLib(const std::string &dlname, bool bCreate);
    int32_t UnloadAngleLib(bool bPreLoad);
    int32_t LoadInnerouterLib(const std::string &dlname, bool bCreate);
    int32_t UnloadInnerouterLib(bool bPreLoad);
    int32_t LoadExistLib(const std::string &dlname, bool bCreate);
    int32_t UnloadExistLib(bool bPreLoad);
    int32_t LoadCommonLib(const std::string &dlname, bool bCreate);
    int32_t UnloadCommonLib(bool bPreLoad);
    MsdpAlgorithmInterface *GetDirectionInst();
    MsdpAlgorithmInterface *GetDistanceInst();
    MsdpAlgorithmInterface *GetAngleInst();
    MsdpAlgorithmInterface *GetInnerouterInst();
    MsdpAlgorithmInterface *GetExistInst();
    MsdpAlgorithmInterface *GetCommonInst();
    void GetLiblaryFiles(std::string path, std::vector<std::string> &files);
    void RegexSearch(std::string sourceString, std::regex regexString, std::smatch& result);

    DirectionAlgorithmHandle mDirectionAlgorithm_;
    DistanceAlgorithmHandle mDistanceAlgorithm_;
    AngleAlgorithmHandle mAngleAlgorithm_;
    InnerOuterAlgorithmHandle mIoAlgorithm_;
    ExistAlgorithmHandle mExistAlgorithm_;
    CommonAlgorithmHandle mCommonAlgo_;
    std::mutex mMutex_;
    std::unordered_map<AlgorithmType, std::string> mServiceDllMap_;
    std::vector<std::string> algorithmLibList_;
};
} // namespace Msdp
} // namespace OHOS
#endif // SPAPTIAL_ALGORITHM_HANDLE_H